package com.sparrow.common.util;

/**
 * 加速器 检测器
 * 这是一个基于心跳检测的防加速器思路，核心是：
 * 约定客户端每秒发送1个心跳包
 * 服务器计算预期心跳数 = （当前时间 - 开始时间）秒数
 * 实际收到的心跳包数与预期对比，允许一定容错阈值delayTolerance
 * 如果实际收到的心跳包明显少于预期，不处理（网络延迟等原因）
 * 如果实际收到的心跳包明显多于预期，判断为加速器行为
 */
public class SpeedHackMonitor {

    private final long startTimeMillis; // 游戏开始时间，单位毫秒
    private int receivedHeartbeats = 0; // 实际收到的心跳数
    private final int delayTolerance; // 容错心跳数阈值

    public SpeedHackMonitor(int delayTolerance) {
        this.startTimeMillis = System.currentTimeMillis();
        this.delayTolerance = delayTolerance;
    }

    /**
     * 收到一个心跳包，调用此方法
     */
    public synchronized void onHeartbeatReceived() {
        receivedHeartbeats++;
    }

    /**
     * 判断是否存在加速行为
     * @return true:检测到加速器行为; false:正常
     */
    public synchronized boolean checkSpeedHack() {
        long now = System.currentTimeMillis();
        long elapsedSeconds = (now - startTimeMillis) / 1000;

        // 预期收到的心跳数
        long expectedHeartbeats = elapsedSeconds;

        // 实际收到的心跳数比预期多 delayTolerance，认为加速
        if (receivedHeartbeats > expectedHeartbeats + delayTolerance) {
            return true;
        }

        // 如果实际收到心跳数少于预期，可能是网络延迟，不判定为加速
        return false;
    }

    // 测试主函数
    public static void main(String[] args) throws InterruptedException {
        SpeedHackMonitor detector = new SpeedHackMonitor(2);

        // 模拟正常心跳，每秒调用一次onHeartbeatReceived
        for (int i = 0; i < 5; i++) {
            Thread.sleep(1000);
            detector.onHeartbeatReceived();
            System.out.println("检测中，是否加速？ " + detector.checkSpeedHack());
        }

        // 模拟加速行为，1秒收到3个心跳包
        for (int i = 0; i < 3; i++) {
            detector.onHeartbeatReceived();
        }
        System.out.println("模拟加速后，检测结果：" + detector.checkSpeedHack());
    }
}

